#ifndef _SIMPLEC_EXECUTE_H
#define _SIMPLEC_EXECUTE_H

#include "Basic.h"
#include "LibIO.h"

namespace SimpleC
{
	namespace Compiler
	{
		using namespace CoreLib::Basic;
		using namespace CoreLib::IO;

		enum class OpCode
		{
			cPush, iPush, dPush, sPush, Pop, sPop, PushEmpty,
			sAdd,
			iAdd, iSub, iMul, iDiv, Mod,
			dAdd, dSub, dMul, dDiv,
			And, Or, Xor,
			BitAnd, BitOr,
			Not, iNeg, dNeg, Inc, Dec,
			Rsh, Lsh,
			iEql, iNeq, iGeq, iLeq, iLess, iGreater,
			dEql, dNeq, dGeq, dLeq, dLess, dGreater,
			i2d, d2i, c2s,
			iLoad, dLoad, cLoad, sLoad, LoadOffset, sLoadOffset, iStore, dStore, cStore, sStore, StoreOffset, sStoreOffset,
			Jump, JumpTrue, JumpFalse, Call, Ret,
		};

		class Instruction
		{
		public:
			OpCode Operator;
			union
			{
				int Operand[2];
				double DoubleOperand;
				int IntOperand;
			};

			Instruction()
			{
				Operand[0] = Operand[1] = 0;
			}
		};

		class FunctionCode
		{
		public:
			bool External;
			int ArgumentSize;
			String Name;
			List<int> StrVarOffsets;
			List<Instruction> Instructions;
			void Dump(TextWriter & writer);

			FunctionCode()
			{
				External = false;
				ArgumentSize = 0;
			}
		};

		class ProgramCode
		{
		public:
			List<RefPtr<FunctionCode>> Functions;
			List<String> StringBuffer;
			void Dump(const String & fileName);
		};
	}
}

#endif